package com.yanqu.road.server.manager.activity.springunionbanquet;

import com.yanqu.road.dao.impl.activity.springunionbanquet.SpringUnionBanquetConfigDaoImpl;
import com.yanqu.road.dao.impl.activity.springunionbanquet.SpringUnionBanquetJoinDataDaoImpl;
import com.yanqu.road.dao.impl.activity.springunionbanquet.SpringUnionBanquetOpenDataDaoImpl;
import com.yanqu.road.dao.impl.activity.springunionbanquet.SpringUnionBanquetUserDataDaoImpl;
import com.yanqu.road.entity.activity.ActivityConfig;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.springunionbanquet.SpringUnionBanquetJoinData;
import com.yanqu.road.entity.activity.springunionbanquet.SpringUnionBanquetOpenData;
import com.yanqu.road.entity.activity.springunionbanquet.SpringUnionBanquetUserData;
import com.yanqu.road.entity.activity.springunionbanquet.config.SpringUnionBanquetAwardInfo;
import com.yanqu.road.entity.activity.springunionbanquet.config.SpringUnionBanquetConfig;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.logic.bussiness.servercenter.ActivityBussiness;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.pb.activity.SpringUnionBanquetProto;
import com.yanqu.road.server.logic.MessageHelper;
import com.yanqu.road.server.manager.user.CrossUserMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

public class CrossSpringUnionBanquetActivity {

    /**
     * 最大宴会id
     */
    private AtomicLong maxBanquetId;

    /**
     * 最大参加id
     */
    private AtomicLong maxJoinId;

    /**
     * 所有宴会
     */
    private Map<Long, UnionBanquetOpenInfo> openMap;

    /**
     * 所有商会
     */
    private Map<String, UnionBanquetUnion> unionMap;

    /**
     * 所有玩家
     */
    private Map<Long, UnionBanquetUser> userMap;


    private List<UnionBanquetUser> needUpdateList = new ArrayList<>();

    private List<UnionBanquetOpenInfo> needUpdateList2 = new ArrayList<>();

    /**
     * 活动信息
     */
    private ActivityInfo activityInfo;

    private int activityId;

    /**
     * 配置
     */
    private SpringUnionBanquetConfig config;

    public CrossSpringUnionBanquetActivity(ActivityInfo activityInfo) {
        this.activityInfo = activityInfo;
        this.activityId = activityInfo.getActivityId();
    }

    public boolean init() {
        if(openMap != null){
            return false;
        }
        reloadConfig();
        loadData();
        return true;
    }

    private void loadData() {

        maxBanquetId = new AtomicLong(new SpringUnionBanquetOpenDataDaoImpl().getMaxBanquetId(activityId));
        maxJoinId = new AtomicLong(new SpringUnionBanquetJoinDataDaoImpl().getMaxJoinId(activityId));

        Map<Long, SpringUnionBanquetOpenData> openDataMap = new SpringUnionBanquetOpenDataDaoImpl().getSpringUnionBanquetOpenData(activityId);
        Map<Long, SpringUnionBanquetJoinData> joinDataMap = new SpringUnionBanquetJoinDataDaoImpl().getSpringUnionBanquetJoinData(activityId);
        Map<Long, SpringUnionBanquetUserData> userDataMap = new SpringUnionBanquetUserDataDaoImpl().getSpringUnionBanquetUserData(activityId);

        userMap = new ConcurrentHashMap<>();
        openMap = new ConcurrentHashMap<>();
        unionMap = new ConcurrentHashMap<>();

        for (Map.Entry<Long, SpringUnionBanquetUserData> entry : userDataMap.entrySet()) {
            SpringUnionBanquetUserData userData = entry.getValue();
            UnionBanquetUser banquetUser = new UnionBanquetUser(userData);
            userMap.put(entry.getKey(), banquetUser);
        }

        for (Map.Entry<Long, SpringUnionBanquetOpenData> entry : openDataMap.entrySet()) {
            SpringUnionBanquetOpenData openData = entry.getValue();
            String unionUid = openData.getUnionUid();
            UnionBanquetUnion banquetUnion = unionMap.get(unionUid);
            if(banquetUnion == null){
                banquetUnion = new UnionBanquetUnion(unionUid);
                unionMap.put(unionUid, banquetUnion);
            }

            UnionBanquetOpenInfo openInfo = new UnionBanquetOpenInfo(openData);
            for (Long joinId : openData.getJoinIdList()) {
                SpringUnionBanquetJoinData joinData = joinDataMap.get(joinId);
                if(joinData != null){
                    openInfo.getJoinDataList().add(joinData);
                    UnionBanquetUser banquetUser = userMap.get(joinData.getUserId());
                    if(banquetUser != null){
                        banquetUser.getJoinDataList().add(joinData);
                    }
                }
            }
            banquetUnion.getOpenInfoList().add(openInfo);
            UnionBanquetUser banquetUser = userMap.get(openData.getOpenUserId());
            if(banquetUser != null){
                banquetUser.getOpenInfoList().add(openInfo);
            }
            openMap.put(openData.getBanquetId(), openInfo);
        }

    }

    public void reloadConfig(){

        List<Integer> activityIdList = new ArrayList<>();
        activityIdList.add(activityInfo.getActivityId());
        Map<String, ActivityConfig> activityConfigMap = ActivityBussiness.getActivityConfigMap(activityIdList).get(activityInfo.getActivityId());

        SpringUnionBanquetConfig banquetConfig = new SpringUnionBanquetConfig(activityInfo);
        banquetConfig.init(activityConfigMap);
        banquetConfig.setAwardInfoList(new SpringUnionBanquetConfigDaoImpl().getSpringUnionBanquetAwardInfoList(this.activityId));

        this.config = banquetConfig;
    }

    public UnionBanquetUser getUnionBanquetUser(long userId){
        UnionBanquetUser banquetUser = userMap.get(userId);
        if(banquetUser == null){
            synchronized (userMap){
                banquetUser = userMap.get(userId);
                if(banquetUser == null){
                    SpringUnionBanquetUserData unionBanquetUserData = initSpringUnionBanquetUserData(userId);
                    banquetUser = new UnionBanquetUser(unionBanquetUserData);
                    userMap.put(userId, banquetUser);
                    synchronized (needUpdateList) {
                        needUpdateList.add(banquetUser);
                    }
                }
            }
        }
        return banquetUser;
    }

    public UnionBanquetUnion getUnionBanquetUnion(String unionUid){
        UnionBanquetUnion unionBanquetUnion = unionMap.get(unionUid);
        if(unionBanquetUnion == null){
            synchronized (unionMap){
                unionBanquetUnion = unionMap.get(unionUid);
                if(unionBanquetUnion == null){
                    unionBanquetUnion = new UnionBanquetUnion(unionUid);
                    unionMap.put(unionUid, unionBanquetUnion);
                }
            }
        }
        return unionBanquetUnion;
    }

    public void save(){

        List<UnionBanquetUser> userList = null;
        synchronized (needUpdateList){
            if(needUpdateList.size() > 0){
                userList = new ArrayList<>(needUpdateList);
                needUpdateList.clear();
            }
        }
        if(userList != null) {
            for (UnionBanquetUser banquetUser : userList) {
                SpringUnionBanquetUserData userData = banquetUser.getUserData();
                if (userData.isInsertOption()) {
                    new SpringUnionBanquetUserDataDaoImpl().add(userData);
                } else if (userData.isUpdateOption()) {
                    new SpringUnionBanquetUserDataDaoImpl().update(userData);
                }
            }
        }

        List<UnionBanquetOpenInfo> list = null;
        synchronized (needUpdateList2){
            if(needUpdateList2.size() > 0){
                list = new ArrayList<>(needUpdateList2);
                needUpdateList2.clear();
            }
        }
        if(list != null){
            for (UnionBanquetOpenInfo openInfo : list) {
                if(openInfo.getOpenData().isInsertOption()){
                    new SpringUnionBanquetOpenDataDaoImpl().add(openInfo.getOpenData());
                }else if(openInfo.getOpenData().isUpdateOption()){
                    new SpringUnionBanquetOpenDataDaoImpl().update(openInfo.getOpenData());
                }
                for (int i = 0; i < openInfo.getJoinDataList().size(); i++) {
                    SpringUnionBanquetJoinData joinData = openInfo.getJoinDataList().get(i);
                    if(joinData.isInsertOption()){
                        new SpringUnionBanquetJoinDataDaoImpl().add(joinData);
                    }else if(joinData.isUpdateOption()){
                        new SpringUnionBanquetJoinDataDaoImpl().update(joinData);
                    }
                }
            }
        }

    }

    /**
     * 宴请
     */
    public void openBanquet(long userId, UserBaseInfo userBaseInfo, String unionUid, int goodsId, int maxMemberCount, List<Long> memberList){

        UnionBanquetUser banquetUser = getUnionBanquetUser(userId);

        UnionBanquetOpenInfo openInfo;
        SpringUnionBanquetOpenData openData;

        Random random = new Random();

        SpringUnionBanquetAwardInfo awardInfo = config.getSpringUnionBanquetAwardInfo(goodsId);

        int resourceIdx = random.nextInt(awardInfo.getResourceList().size());
        int resource = awardInfo.getResourceList().get(resourceIdx);

        synchronized (banquetUser){

            banquetUser.getUserData().setUnionUid(unionUid);

            openData = initSpringUnionBanquetOpenData(userId, unionUid, maxMemberCount, awardInfo.getDishId(), resource);
            openInfo = new UnionBanquetOpenInfo(openData);

            //初始特殊奖励池
            openData.setSpecialPoolList(calSpecialReward(awardInfo.getSpecialAwardList(), random));
            openData.setSpecialTotalCount(openData.getSpecialPoolList().size());

            //初始普通固定奖池
            //个数
            int num = maxMemberCount - openData.getSpecialTotalCount();
            List<String> poolList = calBanquetOrdinaryPool(awardInfo, num);
            openData.setPoolList(poolList);

            banquetUser.getOpenInfoList().add(openInfo);
            banquetUser.getUserData().setOpenNum(1 + banquetUser.getUserData().getOpenNum());


        }

        synchronized (needUpdateList){
            needUpdateList.add(banquetUser);
        }

        openMap.put(openData.getBanquetId(), openInfo);

        synchronized (needUpdateList2) {
            needUpdateList2.add(openInfo);
        }

        UnionBanquetUnion banquetUnion = getUnionBanquetUnion(unionUid);
        synchronized (banquetUnion){
            banquetUnion.getOpenInfoList().add(openInfo);
            banquetUnion.setSyncList(memberList);
        }

        SpringUnionBanquetProto.SpringUnionBanquetInfoTemp.Builder banquetBuilder = getBanquetBuilder(openInfo, true);

        //结果返回
        SpringUnionBanquetProto.CrossSpringUnionBanquetOpenRespMsg.Builder serverMsg = SpringUnionBanquetProto.CrossSpringUnionBanquetOpenRespMsg.newBuilder();
        serverMsg.setRet(0);
        serverMsg.setGoodsId(goodsId);
        serverMsg.setUnionUid(unionUid);
        serverMsg.setBanquet(banquetBuilder);
        MessageHelper.sendPacket(userBaseInfo.getServerId(), userId, YanQuMessageUtils.buildMessage(Protocol.S_SPRING_UNION_BANQUET_OPEN_FROM_CROSS, serverMsg));

        //推送玩家
        syncOpenInfoChange(banquetUnion, openInfo, userId);

    }

    private List<String> calBanquetOrdinaryPool(SpringUnionBanquetAwardInfo awardInfo, int num) {
        List<String> list = new ArrayList<>();
        if(num == 0){
            return list;
        }
        int goodsId = 0;
        long average = 0;
        Property property = PropertyHelper.parseStringToProperty(awardInfo.getOrdinaryAverage());
        for (Map.Entry<Integer, BigInteger> entry : property.getGoods().entrySet()) {
            goodsId = entry.getKey();
            average = entry.getValue().longValue();
            break;
        }
        //总数
        long total = average * num;
        //保底总数
        long totalBase = awardInfo.getOrdinaryLeast() * num;
        //随机的总数
        long sub = total - totalBase;
        List<Long> addList = new ArrayList<>();
        if(sub > 0){
            Random random = new Random();
            long totalWeight = 0;
            List<Integer> weightList = new ArrayList<>();
            for (int i = 0; i < num; i++) {
                int w = random.nextInt(1000);
                weightList.add(w);
                totalWeight += w;
            }
            long totalVal = 0;
            for (int i = 0; i < num; i++) {
                long value = BigDecimal.valueOf(sub).multiply(BigDecimal.valueOf(weightList.get(i))).divide(BigDecimal.valueOf(totalWeight), 0, BigDecimal.ROUND_UP).longValue();
                if(totalVal + value > sub){
                    value = sub - totalVal;
                }
                addList.add(value);
                totalVal += value;
            }
        }

        for (int i = 0; i < num; i++) {
            String reward = goodsId + "=" + (awardInfo.getOrdinaryLeast() + (addList.size() > i ? addList.get(i) : 0));
            list.add(reward);
        }
        return list;
    }

    /**
     * 同步最新宴请状态给商会成员
     * @param banquetUnion
     * @param openInfo
     * @param userId
     */
    private void syncOpenInfoChange(UnionBanquetUnion banquetUnion, UnionBanquetOpenInfo openInfo, long userId) {
        SpringUnionBanquetProto.SpringUnionBanquetInfoTemp.Builder banquetBuilder = getBanquetBuilder(openInfo, true);
        for (Long uid : banquetUnion.getNeedSyncList()) {
            UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(uid);
            if(userBaseInfo == null){
                continue;
            }
            SpringUnionBanquetProto.SpringUnionBanquetInfoSyncMsg.Builder sync = SpringUnionBanquetProto.SpringUnionBanquetInfoSyncMsg.newBuilder();
            sync.addBanquet(banquetBuilder);
            MessageHelper.sendPacket(userBaseInfo.getServerId(), uid, YanQuMessageUtils.buildMessage(Protocol.U_SPRING_UNION_BANQUET_SYNC, sync));
        }
    }


    public void joinBanquet(long userId, UserBaseInfo userBaseInfo, String unionUid, long banquetId) {

        UnionBanquetUser banquetUser = getUnionBanquetUser(userId);

        banquetUser.getUserData().setUnionUid(unionUid);

        SpringUnionBanquetProto.CrossSpringUnionBanquetJoinRespMsg.Builder serverMsg = SpringUnionBanquetProto.CrossSpringUnionBanquetJoinRespMsg.newBuilder();

        UnionBanquetUnion banquetUnion = getUnionBanquetUnion(unionUid);

        UnionBanquetOpenInfo openInfo = banquetUnion.findById(banquetId);

        SpringUnionBanquetJoinData banquetJoinData;
        if(openInfo != null){

            Property property = new Property();
            //玩家锁
            synchronized (banquetUser) {

                //商会锁
                synchronized (banquetUnion) {
                    banquetJoinData = openInfo.findJoinByUserId(userId);
                    if (banquetJoinData != null) {
                        SpringUnionBanquetProto.SpringUnionBanquetJoinRespMsg.Builder clientMsg = SpringUnionBanquetProto.SpringUnionBanquetJoinRespMsg.newBuilder();
                        clientMsg.setRet(GameErrorCode.E_SPRING_UNION_BANQUET_HAD_JOIN);
                        MessageHelper.sendPacket(userBaseInfo.getServerId(), userId, YanQuMessageUtils.buildMessage(Protocol.U_SPRING_UNION_BANQUET_JOIN, clientMsg));
                        return;
                    }
                    SpringUnionBanquetOpenData openData = openInfo.getOpenData();

                    long nowTime = System.currentTimeMillis();
                    //判断是否过期
                    if(nowTime > openData.getEndTime()){
                        SpringUnionBanquetProto.SpringUnionBanquetJoinRespMsg.Builder clientMsg = SpringUnionBanquetProto.SpringUnionBanquetJoinRespMsg.newBuilder();
                        clientMsg.setRet(GameErrorCode.E_SPRING_UNION_BANQUET_HAD_END);
                        MessageHelper.sendPacket(userBaseInfo.getServerId(), userId, YanQuMessageUtils.buildMessage(Protocol.U_SPRING_UNION_BANQUET_JOIN, clientMsg));
                        return;
                    }

                    //判断是否奖励发放完
                    if(openData.getMaxLimitCount() <= openInfo.getJoinDataList().size() ||
                        openData.getMaxLimitCount() <= openData.getJoinIdList().size()){
                        SpringUnionBanquetProto.SpringUnionBanquetJoinRespMsg.Builder clientMsg = SpringUnionBanquetProto.SpringUnionBanquetJoinRespMsg.newBuilder();
                        clientMsg.setRet(GameErrorCode.E_SPRING_UNION_BANQUET_HAD_END);
                        MessageHelper.sendPacket(userBaseInfo.getServerId(), userId, YanQuMessageUtils.buildMessage(Protocol.U_SPRING_UNION_BANQUET_JOIN, clientMsg));
                        return;
                    }
                    SpringUnionBanquetAwardInfo awardInfo = config.getSpringUnionBanquetAwardInfo(openData.getConfigId());

                    //特殊奖励 随机
                    banquetJoinData = new SpringUnionBanquetJoinData();

                    Random random = new Random();
                    //大于0 就是特殊奖励
                    int i = random.nextInt(2);

                    //剩余的是否都是特殊奖励
                    //剩余特殊奖励 大于 剩余奖励
                    boolean specialReward = (openData.getSpecialTotalCount() - openData.getSpecialCount()) >= (openData.getMaxLimitCount() - openData.getJoinIdList().size());

                    //计算奖励,是拿特殊奖励
                    if((i > 0 || specialReward) && openData.getSpecialTotalCount() > openData.getSpecialCount()){
                        //特殊奖励
                        String reward = openData.getSpecialPoolList().remove(random.nextInt(openData.getSpecialPoolList().size()));
                        banquetJoinData.setReward(reward);
                        property.addProperty(PropertyHelper.parseStringToProperty(reward));

                        openData.setSpecialCount(1 + openData.getSpecialCount());
                    }else {
                        String reward = openData.getPoolList().remove(random.nextInt(openData.getPoolList().size()));
                        banquetJoinData.setReward(reward);
                        property.addProperty(PropertyHelper.parseStringToProperty(reward));
                    }

                    //初始加入
                    banquetJoinData.setJoinId(maxJoinId.incrementAndGet());
                    banquetJoinData.setJoinTime(System.currentTimeMillis());
                    banquetJoinData.setActivityId(activityId);
                    banquetJoinData.setUserId(userId);
                    banquetJoinData.setBanquetId(banquetId);
                    banquetJoinData.setInsertOption();
                    openInfo.getJoinDataList().add(banquetJoinData);
                    openData.getJoinIdList().add(banquetJoinData.getJoinId());
                    openData.setUpdateOption();

                }
                banquetUser.getJoinDataList().add(banquetJoinData);

            }

            synchronized (needUpdateList2){
                needUpdateList2.add(openInfo);
            }

            //返回
            serverMsg.setRet(0);
            serverMsg.setReward(PropertyHelper.parsePropertyToString(property));
            serverMsg.setBanquet(getBanquetBuilder(openInfo, true));
            serverMsg.setJoin(getBanquetJoinBuilder(banquetJoinData));
            MessageHelper.sendPacket(userBaseInfo.getServerId(), userId, YanQuMessageUtils.buildMessage(Protocol.S_SPRING_UNION_BANQUET_JOIN_FROM_CROSS, serverMsg));

            //同步其他玩家加入
            syncOpenInfoChange(banquetUnion, openInfo, userId);

        }else {
            SpringUnionBanquetProto.SpringUnionBanquetJoinRespMsg.Builder clientMsg = SpringUnionBanquetProto.SpringUnionBanquetJoinRespMsg.newBuilder();
            clientMsg.setRet(GameErrorCode.E_SPRING_UNION_BANQUET_BANQUET_FOUND);
            MessageHelper.sendPacket(userBaseInfo.getServerId(), userId, YanQuMessageUtils.buildMessage(Protocol.U_SPRING_UNION_BANQUET_JOIN, clientMsg));
        }
    }

    private List<String> calSpecialReward(List<String> specialAwardList, Random random) {
        List<String> poolList = new ArrayList<>();
        List<Integer> weightList = new ArrayList<>();
        for (String award : specialAwardList) {
            List<String> paramList = StringUtils.stringToStringList(award, ",");
            poolList.add(paramList.get(0));
            weightList.add(Integer.parseInt(paramList.get(1)));
        }
        List<String> itemList = new ArrayList<>();
        while (poolList.size() > 0){
            int index = RandomHelper.getRandomIndexByWeight(weightList, random);
            String remove = poolList.remove(index);
            weightList.remove(index);
            itemList.add(remove);
        }
        return itemList;
    }


    /**
     * 查商会开的宴请
     */
    public void list(long serverId, long playerId, String unionUid) {
        SpringUnionBanquetProto.SpringUnionBanquetListRespMsg.Builder clientMsg = SpringUnionBanquetProto.SpringUnionBanquetListRespMsg.newBuilder();

        List<SpringUnionBanquetProto.SpringUnionBanquetInfoTemp> list = getSpringUnionBanquetInfoTemps(unionUid);
        clientMsg.addAllBanquet(list);
        clientMsg.setRet(0);
        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.U_SPRING_UNION_BANQUET_LIST, clientMsg));
    }


    public void loginSyncList(long serverId, long playerId, String unionUid, List<Long> memberList) {
        SpringUnionBanquetProto.SpringUnionBanquetInfoSyncMsg.Builder clientMsg = SpringUnionBanquetProto.SpringUnionBanquetInfoSyncMsg.newBuilder();

        UnionBanquetUnion banquetUnion = unionMap.get(unionUid);
        if(banquetUnion != null){
            banquetUnion.setSyncList(memberList);
        }

        List<SpringUnionBanquetProto.SpringUnionBanquetInfoTemp> list = getSpringUnionBanquetInfoTemps(unionUid);
        clientMsg.addAllBanquet(list);
        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.U_SPRING_UNION_BANQUET_SYNC, clientMsg));
    }

    private List<SpringUnionBanquetProto.SpringUnionBanquetInfoTemp> getSpringUnionBanquetInfoTemps(String unionUid) {

        List<SpringUnionBanquetProto.SpringUnionBanquetInfoTemp> list = new ArrayList<>();
        if(StringUtils.isNullOrEmpty(unionUid)){
            return list;
        }
        UnionBanquetUnion banquetUnion = unionMap.get(unionUid);
        if(banquetUnion != null){
            int num = 0;
            List<UnionBanquetOpenInfo> openInfoList = banquetUnion.getOpenInfoList();
            for (int i = 0; i < openInfoList.size(); i++) {
                UnionBanquetOpenInfo openInfo = openInfoList.get(i);

                if(isEnd(openInfo)){
                    //continue;
                }

                SpringUnionBanquetOpenData openData = openInfo.getOpenData();

                UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(openData.getOpenUserId());
                if(userBaseInfo == null){
                    continue;
                }

                SpringUnionBanquetProto.SpringUnionBanquetInfoTemp.Builder banquetBuilder = getBanquetBuilder(openInfo, false);
                list.add(banquetBuilder.build());
                num++;
                if(num >= config.getFootLimit()){
                    //break;
                }
            }
        }
        return list;
    }

    private boolean isEnd(UnionBanquetOpenInfo openInfo) {
        if(System.currentTimeMillis() >= openInfo.getOpenData().getEndTime()){
            return true;
        }
        if(openInfo.getOpenData().getJoinIdList().size() >= openInfo.getOpenData().getMaxLimitCount()){
            return true;
        }
        return false;
    }


    private SpringUnionBanquetProto.SpringUnionBanquetInfoTemp.Builder getBanquetBuilder(UnionBanquetOpenInfo openInfo, boolean containJoinDetail) {
        SpringUnionBanquetOpenData openData = openInfo.getOpenData();
        SpringUnionBanquetProto.SpringUnionBanquetInfoTemp.Builder banquetBuilder = SpringUnionBanquetProto.SpringUnionBanquetInfoTemp.newBuilder();
        banquetBuilder.setBanquetId(openData.getBanquetId());
        banquetBuilder.setConfigId(openData.getConfigId());
        banquetBuilder.setEndTime(openData.getEndTime());
        banquetBuilder.setGetSpecialCount(openData.getSpecialCount());
        banquetBuilder.setMaxLimitCount(openData.getMaxLimitCount());
        banquetBuilder.setOpenTime(openData.getOpenTime());
        banquetBuilder.setOpenUserId(openData.getOpenUserId());
        banquetBuilder.setResource(openData.getResource());
        banquetBuilder.setUnionUid(openData.getUnionUid());
        UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(openData.getOpenUserId());
        if(userBaseInfo != null){
            banquetBuilder.setUserBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
        }

        if(containJoinDetail) {
            List<SpringUnionBanquetJoinData> joinDataList = openInfo.getJoinDataList();
            for (int k = 0; k < joinDataList.size(); k++) {
                SpringUnionBanquetJoinData joinData = joinDataList.get(k);
                SpringUnionBanquetProto.SpringUnionBanquetJoinInfoTemp.Builder joinInfoTemp = getBanquetJoinBuilder(joinData);
                if (joinInfoTemp == null) continue;
                banquetBuilder.addJoin(joinInfoTemp);
            }
        }

        List<SpringUnionBanquetJoinData> joinDataList = openInfo.getJoinDataList();
        for (int k = 0; k < joinDataList.size(); k++) {
            SpringUnionBanquetJoinData joinData = joinDataList.get(k);
            banquetBuilder.addJoinUser(joinData.getUserId());
        }

        return banquetBuilder;
    }


    public void myOpenList(long playerId, long serverId, int page, int pageSize) {

        SpringUnionBanquetProto.SpringUnionBanquetMyOpenListRespMsg.Builder clientMsg = SpringUnionBanquetProto.SpringUnionBanquetMyOpenListRespMsg.newBuilder();
        clientMsg.setRet(0);
        clientMsg.setPage(page);

        UnionBanquetUser unionBanquetUser = getUnionBanquetUser(playerId);

        List<UnionBanquetOpenInfo> openInfoList = unionBanquetUser.getOpenInfoList();
        int sendTimes = 0;
        for (UnionBanquetOpenInfo openInfo : openInfoList) {
            sendTimes += openInfo.getOpenData().getJoinIdList().size();
        }

//        unionBanquetUser.getUserData().getOpenNum()
        clientMsg.setOpenTimes(openInfoList.size());
        clientMsg.setSendTimes(sendTimes);

        int size = openInfoList.size();

        if(size > 0) {
            int num = pageSize;
            int lastIndex = size - 1;
            int start = lastIndex - (page - 1) * pageSize;
            if (start < 0 || start > lastIndex) {
                start = lastIndex;
            }
            for (int i = start; i >= 0 && num > 0; i--,num--) {
                UnionBanquetOpenInfo openInfo = openInfoList.get(i);
                SpringUnionBanquetProto.SpringUnionBanquetSimpleOpenInfoTemp.Builder builder = SpringUnionBanquetProto.SpringUnionBanquetSimpleOpenInfoTemp.newBuilder();
                builder.setBanquetId(openInfo.getOpenData().getBanquetId());
                builder.setConfigId(openInfo.getOpenData().getConfigId());
                builder.setSendTimes(openInfo.getOpenData().getJoinIdList().size());
                builder.setOpenTime(openInfo.getOpenData().getOpenTime());
                builder.setResource(openInfo.getOpenData().getResource());
                clientMsg.addOpen(builder);
            }
        }

        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.U_SPRING_UNION_BANQUET_MY_OPEN_LIST, clientMsg));
    }


    public void myJoinList(long playerId, long serverId, int page, int pageSize) {

        SpringUnionBanquetProto.SpringUnionBanquetMyJoinListRespMsg.Builder clientMsg = SpringUnionBanquetProto.SpringUnionBanquetMyJoinListRespMsg.newBuilder();
        clientMsg.setRet(0);
        clientMsg.setPage(page);

        UnionBanquetUser unionBanquetUser = getUnionBanquetUser(playerId);

        clientMsg.setJoinTimes(unionBanquetUser.getJoinDataList().size());

        int size = unionBanquetUser.getJoinDataList().size();

        if(size > 0) {
            int num = pageSize;
            int lastIndex = size - 1;
            int start = lastIndex - (page - 1) * pageSize;
            if (start < 0 || start > lastIndex) {
                start = lastIndex;
            }
            for (int i = start; i >= 0 && num > 0; i--,num--) {
                SpringUnionBanquetJoinData joinData = unionBanquetUser.getJoinDataList().get(i);
                SpringUnionBanquetProto.SpringUnionBanquetSimpleJoinInfoTemp.Builder builder = SpringUnionBanquetProto.SpringUnionBanquetSimpleJoinInfoTemp.newBuilder();
                builder.setBanquetId(joinData.getBanquetId());
                UnionBanquetOpenInfo openInfo = openMap.get(joinData.getBanquetId());
                builder.setOpenUserId(openInfo.getOpenData().getOpenUserId());
                builder.setConfigId(openInfo.getOpenData().getConfigId());
                builder.setResource(openInfo.getOpenData().getResource());
                UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(openInfo.getOpenData().getOpenUserId());
                builder.setUserBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
                builder.setJoinTime(joinData.getJoinTime());
                builder.setReward(joinData.getReward());
                clientMsg.addJoin(builder);
            }
        }

        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.U_SPRING_UNION_BANQUET_MY_JOIN_LIST, clientMsg));
    }

    public void getUnionBanquetDetail(long serverId, long playerId, long banquetId) {

        SpringUnionBanquetProto.SpringUnionBanquetDetailRespMsg.Builder clientMsg = SpringUnionBanquetProto.SpringUnionBanquetDetailRespMsg.newBuilder();

        UnionBanquetOpenInfo openInfo = openMap.get(banquetId);
        if(openInfo != null){
            clientMsg.setBanquet(getBanquetBuilder(openInfo, true));
            clientMsg.setRet(0);
        }else {
            clientMsg.setRet(-1);
        }

        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.U_SPRING_UNION_BANQUET_DETAIL, clientMsg));
    }


    public void updateMemberList(String unionUid, List<Long> list) {
        UnionBanquetUnion banquetUnion = unionMap.get(unionUid);
        if(banquetUnion != null){
            banquetUnion.setSyncList(list);
        }
    }

    public void syncTopUser(String unionUid, long serverId, long playerId, List<Long> memberList) {
        UnionBanquetUnion banquetUnion = getUnionBanquetUnion(unionUid);
        SpringUnionBanquetProto.SpringUnionBanquetUnionTopRespMsg.Builder clientMsg = SpringUnionBanquetProto.SpringUnionBanquetUnionTopRespMsg.newBuilder();
        clientMsg.setRet(0);
        if(banquetUnion != null){
            banquetUnion.setSyncList(memberList);
            List<UnionBanquetUser> topList = new ArrayList<>();
            for (Long uid : banquetUnion.getNeedSyncList()) {
                UnionBanquetUser banquetUser = userMap.get(uid);
                if(banquetUser != null && playerId != uid){
                    topList.add(banquetUser);
                }
            }
            topList.sort((o1, o2) -> o2.getUserData().getOpenNum() - o1.getUserData().getOpenNum());
            int i = 0;
            for (UnionBanquetUser banquetUser : topList) {
                SpringUnionBanquetProto.SpringUnionBanquetUserTemp.Builder builder = SpringUnionBanquetProto.SpringUnionBanquetUserTemp.newBuilder();
                builder.setUserId(banquetUser.getUserData().getUserId());
                builder.setOpenNum(banquetUser.getUserData().getOpenNum());
                UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(banquetUser.getUserData().getUserId());
                if(userBaseInfo == null){
                    continue;
                }
                builder.setUserBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
                clientMsg.addUser(builder);
                i++;
                if(i >= 3){
                    break;
                }
            }
            if(clientMsg.getUserCount() < 3){
                List<Long> poolList = new ArrayList<>(banquetUnion.getNeedSyncList());
                poolList.remove(playerId);
                for (SpringUnionBanquetProto.SpringUnionBanquetUserTemp temp : clientMsg.getUserList()) {
                    poolList.remove(temp.getUserId());
                }
                Random random = new Random();
                while (clientMsg.getUserCount() < 3 && poolList.size() > 0){
                    Long uid = poolList.remove(random.nextInt(poolList.size()));
                    UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(uid);
                    if(userBaseInfo == null){
                        continue;
                    }
                    SpringUnionBanquetProto.SpringUnionBanquetUserTemp.Builder builder = SpringUnionBanquetProto.SpringUnionBanquetUserTemp.newBuilder();
                    builder.setUserId(uid);
                    builder.setOpenNum(0);
                    builder.setUserBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
                    clientMsg.addUser(builder);
                }
            }
        }

        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.U_SPRING_UNION_BANQUET_UNION_TOP, clientMsg));
    }

    private SpringUnionBanquetProto.SpringUnionBanquetJoinInfoTemp.Builder getBanquetJoinBuilder(SpringUnionBanquetJoinData joinData) {
        SpringUnionBanquetProto.SpringUnionBanquetJoinInfoTemp.Builder joinInfoTemp = SpringUnionBanquetProto.SpringUnionBanquetJoinInfoTemp.newBuilder();
        joinInfoTemp.setUserId(joinData.getUserId());
        joinInfoTemp.setJoinId(joinData.getJoinId());
        joinInfoTemp.setJoinTime(joinData.getJoinTime());
        joinInfoTemp.setReward(joinData.getReward());
        UserBaseInfo myInfo = CrossUserMgr.getUserBaseInfo(joinData.getUserId());
        if(myInfo != null){
            joinInfoTemp.setUserBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(myInfo));
        }
        return joinInfoTemp;
    }

    public SpringUnionBanquetUserData initSpringUnionBanquetUserData(long userId){
        SpringUnionBanquetUserData userData = new SpringUnionBanquetUserData();
        userData.setActivityId(activityId);
        userData.setUserId(userId);
        userData.setInsertOption();
        return userData;
    }

    public SpringUnionBanquetOpenData initSpringUnionBanquetOpenData(long userId, String unionUid, int maxMemberCount, int configId, int resource){
        SpringUnionBanquetOpenData openData = new SpringUnionBanquetOpenData();
        openData.setActivityId(activityId);
        openData.setOpenUserId(userId);
        openData.setOpenTime(System.currentTimeMillis());
        openData.setBanquetId(maxBanquetId.incrementAndGet());
        openData.setEndTime(openData.getOpenTime() + config.getFoodOutTime() * 1000);
        openData.setJoinIdList(new ArrayList<>());
        openData.setUnionUid(unionUid);
        openData.setMaxLimitCount(maxMemberCount);
        openData.setConfigId(configId);
        openData.setResource(resource);
        openData.setInsertOption();
        openData.setUnionUid(unionUid);
        return openData;
    }

}
